package com.ymatou.iapi.payment.testcase;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import com.ymatou.iapi.payment.parameter.AcquireOrderBean;
import com.ymatou.iapi.payment.parameter.SubmitRefundBean;
import com.ymatou.iapi.payment.parameter.TradeDetail;
import com.ymatou.iapi.payment.service.SubmitRefundCall;
import com.ymt.core.tool.FormatUtil;
import com.ymt.core.tool.Logger;
import com.ymt.utils.annotation.TestCase;
import com.ymt.utils.annotation.TestSuite;
import com.ymt.utils.tag.P1;
import com.ymt.utils.tag.P2;
import com.ymt.utils.tag.P3;
import com.ymttest.business.data.Sign;
import com.ymttest.business.service.PayGateWayCallService;
import com.ymttest.database.model.MPayment;
import com.ymttest.database.model.MRefund;
import com.ymttest.database.sqlwapper.PayGateWayWapper;
import com.ymttest.utils.TestDataManager;

/**
 * 提交退款接口 FreeMaker Template自动生成代码
 */
@TestSuite
public class Ts_SubmitRefund {
	private static SubmitRefundBean submitrefundBean;
	private static SubmitRefundCall submitrefundCall;
	private static PayGateWayWapper paymentwapper;

	@BeforeClass
	public static void setUp() {
		Logger.createResultFile("提交退款接口");
	}

	@Before
	public void caseUp() {
		submitrefundBean = new SubmitRefundBean();
		submitrefundCall = new SubmitRefundCall();
		paymentwapper = new PayGateWayWapper();
	}

	@AfterClass
	public static void tearDown() {
		Logger.generateResult(submitrefundCall.getOpurl());
	}

	@After
	public void caseDown() {
		Logger.end();
	}

	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_SubmitRefund_001() {
		Logger.start(true, "提交退款成功");
		try {
			AcquireOrderBean aqb = PayGateWayCallService.initAcquireOrder("10");
			PayGateWayCallService.acquireOrder(aqb);
			PayGateWayCallService.notifyCall(aqb);
			submitrefundBean.setAppId("AutoTest");
			submitrefundBean.setOrderId(TestDataManager.getRandomNum(12));
			submitrefundBean.setTraceId(TestDataManager.getRandomUUID().toString().replace("-", ""));
			List<TradeDetail> TradeDetails = new ArrayList<TradeDetail>();
			TradeDetail td = new TradeDetail();
			td.setTradeNo(aqb.getOrderId());
			td.setTradeType("2");
			TradeDetails.add(td);
			submitrefundBean.setTradeDetails(TradeDetails);
			String sign = new Sign().signMd5(submitrefundBean, Sign.autoTestKey);
			submitrefundBean.setSign(sign);
			submitrefundCall.setData(submitrefundBean);
			submitrefundCall.callService();
			Logger.comment("验证返回信息");
			Map m = submitrefundCall.getMap();
			Logger.verifyEquals(0d, m.get("ErrorCode"), "验证ErrorCode");
			ArrayList<Map> details = (ArrayList<Map>) m.get("Details");
			Logger.comment("验证Details");
			String tradeNo = details.get(0).get("TradeNo").toString();
			boolean isRefundable = (Boolean) details.get(0).get("IsRefundable");
			Logger.verifyEquals(aqb.getOrderId(), tradeNo, "验证tradeNo");
			Logger.verifyEquals(true, isRefundable, "验证isRefundable");
			verifyDB(aqb, submitrefundBean);
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({ P3.class })
	@TestCase
	public void Tc_SubmitRefund_002() {
		Logger.start(false, "不输入OrderId提交退款失败");
		try {
			AcquireOrderBean aqb = PayGateWayCallService.initAcquireOrder("10");
			PayGateWayCallService.acquireOrder(aqb);
			PayGateWayCallService.notifyCall(aqb);
			submitrefundBean.setAppId("AutoTest");
			// submitrefundBean.setOrderId(TestDataManager.getRandomNum(12));
			submitrefundBean.setTraceId(TestDataManager.getRandomUUID().toString().replace("-", ""));
			List<TradeDetail> TradeDetails = new ArrayList<TradeDetail>();
			TradeDetail td = new TradeDetail();
			td.setTradeNo(aqb.getOrderId());
			td.setTradeType("2");
			TradeDetails.add(td);
			submitrefundBean.setTradeDetails(TradeDetails);
			String sign = new Sign().signMd5(submitrefundBean, Sign.autoTestKey);
			submitrefundBean.setSign(sign);
			submitrefundCall.setData(submitrefundBean);
			submitrefundCall.callService();
			Logger.comment("验证返回信息");
			Map m = submitrefundCall.getMap();
			Logger.verifyEquals(1000d, m.get("ErrorCode"), "验证ErrorCode");
			Logger.verifyIsContains("orderId is empty", m.get("ErrorMessage"), "验证ErrorMessage");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({ P3.class })
	@TestCase
	public void Tc_SubmitRefund_003() {
		Logger.start(false, "不输入TradeDetails提交退款失败");
		try {
			AcquireOrderBean aqb = PayGateWayCallService.initAcquireOrder("10");
			PayGateWayCallService.acquireOrder(aqb);
			PayGateWayCallService.notifyCall(aqb);
			submitrefundBean.setAppId("AutoTest");
			submitrefundBean.setOrderId(TestDataManager.getRandomNum(12));
			submitrefundBean.setTraceId(TestDataManager.getRandomUUID().toString().replace("-", ""));
			List<TradeDetail> TradeDetails = new ArrayList<TradeDetail>();
			TradeDetail td = new TradeDetail();
			td.setTradeNo(aqb.getOrderId());
			td.setTradeType("2");
			TradeDetails.add(td);
			// submitrefundBean.setTradeDetails(TradeDetails);
			String sign = new Sign().signMd5(submitrefundBean, Sign.autoTestKey);
			submitrefundBean.setSign(sign);
			submitrefundCall.setData(submitrefundBean);
			submitrefundCall.callService();
			Logger.comment("验证返回信息");
			Map m = submitrefundCall.getMap();
			Logger.verifyEquals(1000d, m.get("ErrorCode"), "验证ErrorCode");
			Logger.verifyIsContains("tradeDetails is empty", m.get("ErrorMessage"), "验证ErrorMessage");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({ P3.class })
	@TestCase
	public void Tc_SubmitRefund_004() {
		Logger.start(false, "不输入AppId提交退款失败");
		try {
			AcquireOrderBean aqb = PayGateWayCallService.initAcquireOrder("10");
			PayGateWayCallService.acquireOrder(aqb);
			PayGateWayCallService.notifyCall(aqb);
			// submitrefundBean.setAppId("AutoTest");
			submitrefundBean.setOrderId(TestDataManager.getRandomNum(12));
			submitrefundBean.setTraceId(TestDataManager.getRandomUUID().toString().replace("-", ""));
			List<TradeDetail> TradeDetails = new ArrayList<TradeDetail>();
			TradeDetail td = new TradeDetail();
			td.setTradeNo(aqb.getOrderId());
			td.setTradeType("2");
			TradeDetails.add(td);
			submitrefundBean.setTradeDetails(TradeDetails);
			String sign = new Sign().signMd5(submitrefundBean, Sign.autoTestKey);
			submitrefundBean.setSign(sign);
			submitrefundCall.setData(submitrefundBean);
			submitrefundCall.callService();
			Logger.comment("验证返回信息");
			Map m = submitrefundCall.getMap();
			Logger.verifyEquals(1000d, m.get("ErrorCode"), "验证ErrorCode");
			Logger.verifyIsContains("appId is empty", m.get("ErrorMessage"), "验证ErrorMessage");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({ P3.class })
	@TestCase
	public void Tc_SubmitRefund_005() {
		Logger.start(false, "不输入TraceId提交退款失败");
		try {
			AcquireOrderBean aqb = PayGateWayCallService.initAcquireOrder("10");
			PayGateWayCallService.acquireOrder(aqb);
			PayGateWayCallService.notifyCall(aqb);
			submitrefundBean.setAppId("AutoTest");
			submitrefundBean.setOrderId(TestDataManager.getRandomNum(12));
			// submitrefundBean.setTraceId(TestDataManager.getRandomUUID().toString().replace("-",
			// ""));
			List<TradeDetail> TradeDetails = new ArrayList<TradeDetail>();
			TradeDetail td = new TradeDetail();
			td.setTradeNo(aqb.getOrderId());
			td.setTradeType("2");
			TradeDetails.add(td);
			submitrefundBean.setTradeDetails(TradeDetails);
			String sign = new Sign().signMd5(submitrefundBean, Sign.autoTestKey);
			submitrefundBean.setSign(sign);
			submitrefundCall.setData(submitrefundBean);
			submitrefundCall.callService();
			Logger.comment("验证返回信息");
			Map m = submitrefundCall.getMap();
			Logger.verifyEquals(1000d, m.get("ErrorCode"), "验证ErrorCode");
			Logger.verifyIsContains("traceId is empty", m.get("ErrorMessage"), "验证ErrorMessage");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({ P3.class })
	@TestCase
	@Ignore
	// 此接口不验签
	public void Tc_SubmitRefund_006() {
		Logger.start(false, "不输入Sign提交退款失败");
		try {
			AcquireOrderBean aqb = PayGateWayCallService.initAcquireOrder("10");
			PayGateWayCallService.acquireOrder(aqb);
			PayGateWayCallService.notifyCall(aqb);
			submitrefundBean.setAppId("AutoTest");
			submitrefundBean.setOrderId(TestDataManager.getRandomNum(12));
			submitrefundBean.setTraceId(TestDataManager.getRandomUUID().toString().replace("-", ""));
			List<TradeDetail> TradeDetails = new ArrayList<TradeDetail>();
			TradeDetail td = new TradeDetail();
			td.setTradeNo(aqb.getOrderId());
			td.setTradeType("2");
			TradeDetails.add(td);
			submitrefundBean.setTradeDetails(TradeDetails);
			// String sign = new Sign().signMd5(submitrefundBean,
			// Sign.autoTestKey);
			// submitrefundBean.setSign(sign);
			submitrefundCall.setData(submitrefundBean);
			submitrefundCall.callService();
			Logger.comment("验证返回信息");
			Map m = submitrefundCall.getMap();
			Logger.verifyEquals(-9999d, m.get("ErrorCode"), "验证ErrorCode");
			Logger.verifyEquals("traceid not valid", m.get("ErrorMessage"), "验证ErrorMessage");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_SubmitRefund_007() {
		Logger.start(false, "TradeDetails中提交重复退款记录,只记录一条");
		try {
			AcquireOrderBean aqb = PayGateWayCallService.initAcquireOrder("10");
			PayGateWayCallService.acquireOrder(aqb);
			PayGateWayCallService.notifyCall(aqb);
			submitrefundBean.setAppId("AutoTest");
			submitrefundBean.setOrderId(TestDataManager.getRandomNum(12));
			submitrefundBean.setTraceId(TestDataManager.getRandomUUID().toString().replace("-", ""));
			List<TradeDetail> TradeDetails = new ArrayList<TradeDetail>();
			TradeDetail td = new TradeDetail();
			td.setTradeNo(aqb.getOrderId());
			td.setTradeType("2");
			TradeDetails.add(td);
			TradeDetails.add(td);
			submitrefundBean.setTradeDetails(TradeDetails);
			String sign = new Sign().signMd5(submitrefundBean, Sign.autoTestKey);
			submitrefundBean.setSign(sign);
			submitrefundCall.setData(submitrefundBean);
			submitrefundCall.callService();
			Logger.comment("验证返回信息");
			Map m = submitrefundCall.getMap();
			Logger.verifyEquals(5000d, m.get("ErrorCode"), "验证ErrorCode");
			Logger.verifyEquals("请求处理失败|duplicate trade", m.get("ErrorMessage"), "验证ErrorMessage");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_SubmitRefund_008() {
		Logger.start(true, "重复提交退款记录,只记录一条");
		try {
			AcquireOrderBean aqb = PayGateWayCallService.initAcquireOrder("10");
			PayGateWayCallService.acquireOrder(aqb);
			PayGateWayCallService.notifyCall(aqb);
			submitrefundBean.setAppId("AutoTest");
			submitrefundBean.setOrderId(TestDataManager.getRandomNum(12));
			submitrefundBean.setTraceId(TestDataManager.getRandomUUID().toString().replace("-", ""));
			List<TradeDetail> TradeDetails = new ArrayList<TradeDetail>();
			TradeDetail td = new TradeDetail();
			td.setTradeNo(aqb.getOrderId());
			td.setTradeType("2");
			TradeDetails.add(td);
			TradeDetails.add(td);
			submitrefundBean.setTradeDetails(TradeDetails);
			String sign = new Sign().signMd5(submitrefundBean, Sign.autoTestKey);
			submitrefundBean.setSign(sign);
			submitrefundCall.setData(submitrefundBean);
			submitrefundCall.callService();
			submitrefundCall.callService();
			Logger.comment("验证返回信息");
			Map m = submitrefundCall.getMap();
			Logger.verifyEquals(5000d, m.get("ErrorCode"), "验证ErrorCode");
			Logger.verifyEquals("请求处理失败|duplicate trade", m.get("ErrorMessage"), "验证ErrorMessage");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({ P2.class })
	@TestCase
	public void Tc_SubmitRefund_009() {
		Logger.start(true, "多笔提交退款成功");
		try {
			// TODO 需要确认多笔退款应该如何设置
			AcquireOrderBean aqb = PayGateWayCallService.initAcquireOrder("10");
			PayGateWayCallService.acquireOrder(aqb);
			PayGateWayCallService.notifyCall(aqb);
			AcquireOrderBean aqb2 = aqb;
			aqb2.setAppId("Test");
			Logger.debug("aqb:" + FormatUtil.beanToGSONString(aqb));
			Logger.debug("aqb:" + FormatUtil.beanToGSONString(aqb2));
			submitrefundBean.setAppId("AutoTest");
			submitrefundBean.setOrderId(TestDataManager.getRandomNum(12));
			submitrefundBean.setTraceId(TestDataManager.getRandomUUID().toString().replace("-", ""));
			List<TradeDetail> TradeDetails = new ArrayList<TradeDetail>();
			TradeDetail td = new TradeDetail();
			td.setTradeNo(aqb.getOrderId());
			td.setTradeType("2");
			TradeDetails.add(td);
			submitrefundBean.setTradeDetails(TradeDetails);
			String sign = new Sign().signMd5(submitrefundBean, Sign.autoTestKey);
			submitrefundBean.setSign(sign);
			submitrefundCall.setData(submitrefundBean);
			submitrefundCall.callService();
			Logger.comment("验证返回信息");
			Map m = submitrefundCall.getMap();
			Logger.verifyEquals(0d, m.get("ErrorCode"), "验证ErrorCode");
			ArrayList<Map> details = (ArrayList<Map>) m.get("Details");
			Logger.comment("验证Details");
			String tradeNo = details.get(0).get("TradeNo").toString();
			boolean isRefundable = (Boolean) details.get(0).get("IsRefundable");
			Logger.verifyEquals(aqb.getOrderId(), tradeNo, "验证tradeNo");
			Logger.verifyEquals(true, isRefundable, "验证isRefundable");
			verifyDB(aqb, submitrefundBean);
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_SubmitRefund_010() {
		Logger.start(true, "重复提交,失败");
		try {
			AcquireOrderBean aqb = PayGateWayCallService.initAcquireOrder("10");
			PayGateWayCallService.acquireOrder(aqb);
			PayGateWayCallService.notifyCall(aqb);
			submitrefundBean.setAppId("AutoTest");
			submitrefundBean.setOrderId(TestDataManager.getRandomNum(12));
			submitrefundBean.setTraceId(TestDataManager.getRandomUUID().toString().replace("-", ""));
			List<TradeDetail> TradeDetails = new ArrayList<TradeDetail>();
			TradeDetail td = new TradeDetail();
			td.setTradeNo(aqb.getOrderId());
			td.setTradeType("2");
			TradeDetails.add(td);
			submitrefundBean.setTradeDetails(TradeDetails);
			String sign = new Sign().signMd5(submitrefundBean, Sign.autoTestKey);
			submitrefundBean.setSign(sign);
			submitrefundCall.setData(submitrefundBean);
			submitrefundCall.callService();
			submitrefundCall.callService();
			Logger.comment("验证返回信息");
			Map m = submitrefundCall.getMap();
			Logger.verifyEquals(0d, m.get("ErrorCode"), "验证ErrorCode");
			verifyDB(aqb, submitrefundBean);
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_SubmitRefund_011() {
		Logger.start(true, "微信立减提交退款成功");
		try {
			AcquireOrderBean aqb = PayGateWayCallService.initAcquireOrder("14");
			PayGateWayCallService.acquireOrder(aqb);
			String discountAmt = "2.00";
			String settle = new BigDecimal(aqb.getPayPrice()).subtract(new BigDecimal(discountAmt)).multiply(BigDecimal.valueOf(100)).setScale(0).toString();
			PayGateWayCallService.notifyCall(aqb, discountAmt);
			submitrefundBean.setAppId("AutoTest");
			submitrefundBean.setOrderId(TestDataManager.getRandomNum(12));
			submitrefundBean.setTraceId(TestDataManager.getRandomUUID().toString().replace("-", ""));
			List<TradeDetail> TradeDetails = new ArrayList<TradeDetail>();
			TradeDetail td = new TradeDetail();
			td.setTradeNo(aqb.getOrderId());
			td.setTradeType("2");
			TradeDetails.add(td);
			submitrefundBean.setTradeDetails(TradeDetails);
			String sign = new Sign().signMd5(submitrefundBean, Sign.autoTestKey);
			submitrefundBean.setSign(sign);
			submitrefundCall.setData(submitrefundBean);
			submitrefundCall.callService();
			Logger.comment("验证返回信息");
			Map m = submitrefundCall.getMap();
			Logger.verifyEquals(0d, m.get("ErrorCode"), "验证ErrorCode");
			ArrayList<Map> details = (ArrayList<Map>) m.get("Details");
			Logger.comment("验证Details");
			String tradeNo = details.get(0).get("TradeNo").toString();
			boolean isRefundable = (Boolean) details.get(0).get("IsRefundable");
			Logger.verifyEquals(aqb.getOrderId(), tradeNo, "验证tradeNo");
			Logger.verifyEquals(true, isRefundable, "验证isRefundable");
			verifyDB(aqb, submitrefundBean);
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	private void verifyDB(AcquireOrderBean aqb, SubmitRefundBean srbean) throws Exception {
		Logger.comment("验证数据库RefundRequest");
		MPayment ppm = paymentwapper.selectPaymentByTradingid(aqb.getOrderId()).get(0);
		String trandno = ppm.getPaymentId();
		List<MRefund> mlist = paymentwapper.selectRefundRequestByPaymentId(trandno);
		List<TradeDetail> tlist = srbean.getTradeDetails();
		// 这里实际只会查出一条记录 trandno没有重复？
		Logger.verifyEquals(tlist.size(), mlist.size(), "验证记录条数是否一致");
		for (int i = 0; i < mlist.size(); i++) {
			MRefund m = mlist.get(i);
			Logger.debug("selectRefundRequestByPaymentId:" + FormatUtil.beanToGSONString(m));
			TradeDetail tradeDetail = tlist.get(i);
			Logger.verifyEquals(0, m.getRefundStatus(), "验证RefundStatus");
			Logger.verifyEquals(0, m.getApproveStatus(), "验证ApproveStatus");
			// Logger.verifyEquals(ppm.getInstitutionPaymentId(),
			// m.getInstPaymentId(), "验证InstPaymentId");
			// Logger.verifyEquals(srbean.getAppId(), m.getAppId(), "验证AppId");
			// Logger.verifyEquals(aqb.getCurrency(), m.getCurrencyType(),
			// "验证CurrencyType");
			Logger.verifyEquals(srbean.getOrderId(), m.getOrderId().toString(), "验证OrderId");
			// Logger.verifyEquals(srbean.getTraceId(), m.getTraceId(),
			// "验证TraceId");
			// Logger.verifyEquals(tradeDetail.getTradeType(),
			// m.getTradeType().toString(), "验证TradeType");
			Logger.verifyEquals(tradeDetail.getTradeNo(), m.getTradingId(), "验证TradeNo");
			Logger.verifyNotNull(m.getRefundId(), "验证RefundId非空");
		}
	}
}
